import { connectionModel, type IConnection } from '../database/models';

export interface CreateConnectionData {
  name: string;
  host: string;
  port: number;
  username: string;
  password: string;
  database_name?: string;
  ssl_enabled?: boolean;
  timeout?: number;
  max_connections?: number;
  connection_params?: Record<string, any>;
  created_by?: string;
}

export interface UpdateConnectionData {
  name?: string;
  host?: string;
  port?: number;
  username?: string;
  password?: string;
  database_name?: string;
  ssl_enabled?: boolean;
  timeout?: number;
  max_connections?: number;
  connection_params?: Record<string, any>;
}

export interface ConnectionTestResult {
  success: boolean;
  message: string;
  response_time?: number;
  server_version?: string;
  error_details?: string;
}

export class ConnectionService {
  // 创建连接
  async createConnection(data: CreateConnectionData): Promise<Omit<IConnection, 'password_encrypted'>> {
    // 验证连接数据
    this.validateConnectionData(data);
    
    // 检查连接名称是否唯一
    const isNameUnique = await connectionModel.isNameUnique(data.name);
    if (!isNameUnique) {
      throw new Error('连接名称已存在');
    }
    
    // 验证连接配置
    const validation = await connectionModel.validateConnectionConfig({
      host: data.host,
      port: data.port,
      username: data.username,
      database_name: data.database_name
    });
    
    if (!validation.valid) {
      throw new Error(`连接配置无效: ${validation.errors.join(', ')}`);
    }
    
    // 创建连接
    const connection = await connectionModel.createConnection(data);
    
    // 返回时排除密码字段
    const { password_encrypted, ...connectionWithoutPassword } = connection;
    return connectionWithoutPassword;
  }
  
  // 更新连接
  async updateConnection(id: string, data: UpdateConnectionData): Promise<Omit<IConnection, 'password_encrypted'>> {
    const existingConnection = await connectionModel.getConnectionById(id);
    if (!existingConnection) {
      throw new Error('连接不存在');
    }
    
    // 验证更新数据
    if (data.name || data.host || data.port || data.username || data.database_name) {
      this.validateConnectionData({
        name: data.name || existingConnection.name,
        host: data.host || existingConnection.host,
        port: data.port || existingConnection.port,
        username: data.username || existingConnection.username,
        password: 'dummy', // 密码验证在单独处理
        database_name: data.database_name || existingConnection.database_name
      });
    }
    
    // 检查名称唯一性
    if (data.name && data.name !== existingConnection.name) {
      const isNameUnique = await connectionModel.isNameUnique(data.name, id);
      if (!isNameUnique) {
        throw new Error('连接名称已存在');
      }
    }
    
    // 构建更新数据
    const updateData: any = {};
    if (data.name !== undefined) updateData.name = data.name;
    if (data.host !== undefined) updateData.host = data.host;
    if (data.port !== undefined) updateData.port = data.port;
    if (data.username !== undefined) updateData.username = data.username;
    if (data.database_name !== undefined) updateData.database_name = data.database_name;
    if (data.ssl_enabled !== undefined) updateData.ssl_enabled = data.ssl_enabled;
    if (data.timeout !== undefined) updateData.timeout = data.timeout;
    if (data.max_connections !== undefined) updateData.max_connections = data.max_connections;
    if (data.connection_params !== undefined) updateData.connection_params = JSON.stringify(data.connection_params);
    
    // 更新连接
    await connectionModel.update(id, updateData);
    
    // 如果需要更新密码，单独处理
    if (data.password) {
      await connectionModel.updatePassword(id, data.password);
    }
    
    // 返回更新后的连接信息（不包含密码）
    return await connectionModel.getConnectionById(id);
  }
  
  // 删除连接
  async deleteConnection(id: string): Promise<boolean> {
    const connection = await connectionModel.getConnectionById(id);
    if (!connection) {
      throw new Error('连接不存在');
    }
    
    // 检查是否有正在使用的执行
    const { executionModel } = require('../database/models');
    const runningExecutions = await executionModel.findAll({
      where: { connection_id: id, status: 'running' }
    });
    
    if (runningExecutions.length > 0) {
      throw new Error('连接正在被使用，无法删除');
    }
    
    return await connectionModel.delete(id);
  }
  
  // 获取连接详情
  async getConnection(id: string): Promise<Omit<IConnection, 'password_encrypted'> | null> {
    return await connectionModel.getConnectionById(id);
  }
  
  // 获取连接列表
  async getConnections(options: {
    active_only?: boolean;
    created_by?: string;
    limit?: number;
    offset?: number;
  } = {}): Promise<{
    connections: Omit<IConnection, 'password_encrypted'>[];
    total: number;
    page: number;
    pageSize: number;
  }> {
    const limit = options.limit || 20;
    const offset = options.offset || 0;
    const page = Math.floor(offset / limit) + 1;
    
    let connections: Omit<IConnection, 'password_encrypted'>[];
    let total: number;
    
    if (options.active_only) {
      connections = await connectionModel.getActiveConnections();
      total = connections.length;
      
      // 手动分页
      connections = connections.slice(offset, offset + limit);
    } else {
      const whereConditions: any = {};
      if (options.created_by) {
        whereConditions.created_by = options.created_by;
      }
      
      const allConnections = await connectionModel.findAll({
        where: whereConditions,
        limit,
        offset,
        orderBy: 'created_at',
        orderDirection: 'DESC'
      });
      
      // 移除密码字段
      connections = allConnections.map((conn: any) => {
        const { password_encrypted, ...connectionWithoutPassword } = conn;
        return connectionWithoutPassword;
      });
      
      total = await connectionModel.count(whereConditions);
    }
    
    return {
      connections,
      total,
      page,
      pageSize: limit
    };
  }
  
  // 测试连接
  async testConnection(id: string): Promise<ConnectionTestResult> {
    const connection = await connectionModel.getConnectionForAuth(id);
    if (!connection) {
      return {
        success: false,
        message: '连接不存在'
      };
    }
    
    const startTime = Date.now();
    
    try {
      // 这里应该实际连接到Doris数据库进行测试
      // 由于这是模拟实现，我们只做基本验证
      
      // 验证连接参数
      const validation = await connectionModel.validateConnectionConfig({
        host: connection.host,
        port: connection.port,
        username: connection.username,
        database_name: connection.database_name
      });
      
      if (!validation.valid) {
        return {
          success: false,
          message: '连接配置无效',
          error_details: validation.errors.join(', ')
        };
      }
      
      // 模拟连接测试
      await new Promise(resolve => setTimeout(resolve, 100)); // 模拟网络延迟
      
      const responseTime = Date.now() - startTime;
      
      return {
        success: true,
        message: '连接测试成功',
        response_time: responseTime,
        server_version: 'Doris 2.0.0' // 模拟服务器版本
      };
      
    } catch (error: any) {
      return {
        success: false,
        message: '连接测试失败',
        response_time: Date.now() - startTime,
        error_details: error.message
      };
    }
  }
  
  // 激活/停用连接
  async toggleConnectionStatus(id: string, isActive: boolean): Promise<Omit<IConnection, 'password_encrypted'> | null> {
    const connection = await connectionModel.getConnectionById(id);
    if (!connection) {
      throw new Error('连接不存在');
    }
    
    // 如果要停用连接，检查是否有正在运行的执行
    if (!isActive) {
      const { executionModel } = require('../database/models');
      const runningExecutions = await executionModel.findAll({
        where: { connection_id: id, status: 'running' }
      });
      
      if (runningExecutions.length > 0) {
        throw new Error('连接正在被使用，无法停用');
      }
    }
    
    await connectionModel.toggleActive(id, isActive);
    return await connectionModel.getConnectionById(id);
  }
  
  // 获取连接统计信息
  async getConnectionStats(id: string): Promise<{
    connection: Omit<IConnection, 'password_encrypted'>;
    usage_stats: {
      total_executions: number;
      successful_executions: number;
      failed_executions: number;
      avg_execution_time: number;
      last_used: Date | null;
    };
    recent_executions: any[];
  }> {
    const connection = await connectionModel.getConnectionById(id);
    if (!connection) {
      throw new Error('连接不存在');
    }
    
    const usageStats = await connectionModel.getConnectionStats(id);
    
    // 获取最近执行记录
    const { executionModel } = require('../database/models');
    const recentExecutions = await executionModel.getExecutionsByConnection(id, { limit: 5 });
    
    return {
      connection,
      usage_stats: usageStats,
      recent_executions: recentExecutions.executions
    };
  }
  
  // 批量测试连接
  async testMultipleConnections(connectionIds: string[]): Promise<Array<{
    connection_id: string;
    connection_name: string;
    test_result: ConnectionTestResult;
  }>> {
    const results = [];
    
    for (const connectionId of connectionIds) {
      const connection = await connectionModel.getConnectionById(connectionId);
      const testResult = await this.testConnection(connectionId);
      
      results.push({
        connection_id: connectionId,
        connection_name: connection?.name || '未知连接',
        test_result: testResult
      });
    }
    
    return results;
  }
  
  // 获取连接健康状态
  async getConnectionHealth(): Promise<{
    total_connections: number;
    active_connections: number;
    healthy_connections: number;
    unhealthy_connections: number;
    connections_with_issues: Array<{
      id: string;
      name: string;
      issue: string;
    }>;
  }> {
    const allConnections = await connectionModel.findAll();
    const activeConnections = allConnections.filter((conn: any) => conn.is_active);
    
    let healthyCount = 0;
    let unhealthyCount = 0;
    const connectionsWithIssues = [];
    
    // 检查每个活跃连接的健康状态
    for (const connection of activeConnections) {
      const testResult = await this.testConnection(connection.id);
      
      if (testResult.success) {
        healthyCount++;
      } else {
        unhealthyCount++;
        connectionsWithIssues.push({
          id: connection.id,
          name: connection.name,
          issue: testResult.message
        });
      }
    }
    
    return {
      total_connections: allConnections.length,
      active_connections: activeConnections.length,
      healthy_connections: healthyCount,
      unhealthy_connections: unhealthyCount,
      connections_with_issues: connectionsWithIssues
    };
  }
  
  // 更新连接密码
  async updateConnectionPassword(id: string, newPassword: string): Promise<boolean> {
    const connection = await connectionModel.getConnectionById(id);
    if (!connection) {
      throw new Error('连接不存在');
    }
    
    if (!newPassword || newPassword.length < 6) {
      throw new Error('密码长度不能少于6位');
    }
    
    return await connectionModel.updatePassword(id, newPassword);
  }
  
  // 验证连接数据
  private validateConnectionData(data: Partial<CreateConnectionData>): void {
    if (data.name && (data.name.length < 1 || data.name.length > 255)) {
      throw new Error('连接名称长度必须在1-255个字符之间');
    }
    
    if (data.host && (data.host.length < 1 || data.host.length > 255)) {
      throw new Error('主机地址长度必须在1-255个字符之间');
    }
    
    if (data.port && (data.port < 1 || data.port > 65535)) {
      throw new Error('端口号必须在1-65535之间');
    }
    
    if (data.username && (data.username.length < 1 || data.username.length > 255)) {
      throw new Error('用户名长度必须在1-255个字符之间');
    }
    
    if (data.password && data.password.length < 6) {
      throw new Error('密码长度不能少于6位');
    }
    
    if (data.timeout && (data.timeout < 1000 || data.timeout > 300000)) {
      throw new Error('超时时间必须在1000-300000毫秒之间');
    }
    
    if (data.max_connections && (data.max_connections < 1 || data.max_connections > 100)) {
      throw new Error('最大连接数必须在1-100之间');
    }
    
    if (data.database_name && data.database_name.length > 255) {
      throw new Error('数据库名称长度不能超过255个字符');
    }
  }
}